<?php

namespace App\Components;

use Nette\Application\UI\Control,
		Nette\Utils\Strings,
		Nette\Application\Responses\JsonResponse;

/**
 * Wizard component
 */
class Wizard extends Control {

	/** @var array $steps */
	private $steps = array();

	/**
	 * Add new step to wizard component
	 * 
	 * @param String $id
	 * @param String $title
	 * @param String $info
	 * @param Form $form
	 */
	public function addStep($id, $title, $info, $form = null, $dependency = array()) {
		if($form){
			// Add hidden field to form
			$form->addHidden('step', count($this->steps));
			$form->onSubmit[] = array($this, 'onFormSubmit');
		}
		$this->steps[] = new WizardStep($id, $title, $info, $form, $dependency);
	}

	/**
	 * Return StepWizard from array
	 * 
	 * @param type $index
	 * @return WizardStep
	 */
	public function getStep($index) {
		return $this->steps[$index];
	}
	
	/**
	 * Handle form submit and saves data to cache
	 * 
	 * @param Form $form
	 */
	public function onFormSubmit($form){
		// get form values
		$this->createDependeciesOnSteps();
		$values = $form->getValues();
		// validate form
		$form->validate();
		// get form errors
		$errors = $form->getErrors();
		if(!$errors){
			// load current step and save cache
			$step = $this->getStep($values['step']);
			unset($values['step']); // this parameter is only for orientation
			$step->setCache($values);
			$this->presenter->sendResponse(new JsonResponse(array('status' => true)));
		}else{
			$this->presenter->sendResponse(new JsonResponse(array('status' => false, 'errors' => $errors)));
		}
	}
	
	/**
	 * Handle for redraw forms
	 */
	public function handleGetActualFormFields(){
		
		$this->createDependeciesOnSteps(true);
		$this->redrawControl('staticHelperSnippet');
	}
	
	/**
	 * Handle finishing of wizard - for testing
	 */
	public function handleFinish(){
		$resultArray = array();
		foreach($this->steps as $step){
			$resultArray = array_merge($resultArray, (array) $step->getCache());
			$step->destroyCache();
		}
		
		$_SESSION['result'] = $resultArray;
		$this->presenter->redirect('Homepage:result');
	}

	/**
	 * Create Form steps
	 * 
	 * @param String $name
	 * @return render Form
	 */
	public function createComponent($name) {
		if (Strings::startsWith($name, "wizardForm")) {
			$index = Strings::substring($name, 10);
			if($this->getStep($index)){
				return $this->getStep($index)->getForm();
			}else{
				return parent::createComponent($name);
			}
		} else {
			return parent::createComponent($name);
		}
	}

	/**
	 * Render component
	 */
	public function render() {
		$template = $this->template;
		$template->setFile(__DIR__ . '/wizard.latte');
		$template->steps = $this->steps;
		$template->render();
	}
	
	private function createDependeciesOnSteps($setValues = false){
		// cycle all steps
		foreach($this->steps as $step){
			
			// and their chache
			$cacheArr = $step->getCache();
			$dependencyArr = $step->getDependency();
			
			// for all step cache fields
			foreach($cacheArr as $cacheKey => $cacheValue){

				// set form values if are in cache
				if($setValues && $step->getForm()){
					foreach($step->getForm()->getControls() as $c){
						if($c->getName() == $cacheKey && $cacheValue != ''){
							$c->setDefaultValue($cacheValue);
						}
					}
				}
			
				// for all dependecies on this step
				foreach($dependencyArr as $dependency){
					if($cacheKey == $dependency->getFieldName() && $cacheValue == $dependency->getFieldValue()){
						
						// check dependence and update other step
						foreach($this->steps as $s){
							if($s->getId() == $dependency->getDependentStepId()){
								foreach($dependency->getHide() as $hide){
									$form = $s->getForm();
									unset($form[$hide]);
								}
							}
						}
					}
				}
			}
		}
	}

}
